#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include <sys/wait.h>

//进程回收&退出码
// int main()
// {
//     printf("before fork pid:%d\n",getpid());
//     fork();
//     printf("after fork pid:%d\n",getpid());
//     return 0;
// }


// int main()
// {
//     WNOHANG;//宏，为1
//     pid_t pid=fork();
//     if(pid==0)
//     {
//         // child
//         int cnt = 10;
//         while (cnt--)
//         {
//             printf("I am child pid:%d ppid:%d\n", getpid(), getppid());
//             sleep(1);
//             if (cnt == 0)
//             {
//                 printf("child over\n");
//             }
//         }
//         exit(99);
//     }

//     // pid_t rid=wait(NULL);
//     // father
//     int cnt = 20;
//     while (cnt--)
//     {
//         printf("I am father pid:%d\n", getpid());
//         sleep(1);
//     }

//     int status=0;
//     pid_t rid=waitpid(pid,&status,0);
//     //if(rid>0 && (status&0x7f)==0)//低7位
//     if(rid>0 && WIFEXITED(status))//若为正常终止子进程返回的状态，则为真。（查看进程是否是正常退出,不能看出是几号信号）
//     {
//         printf("wait success:%d exit_code:%d\n",rid,(status>>8)&0xff);
//         printf("wait success:%d exit_code:%d\n",rid,WEXITSTATUS(status));
//     }
//     else
//     {
//         printf("kill by sig:%d\n",status&0x7f);
//         printf("kill by sig:%d\n",status&0x7f);
//     }
//     sleep(5);
//     return 0;
// }


// int main()
// {
//     const char* str="i am a process pid";
//     pid_t pid=getpid();
//     printf("i am a process pid %d\n",pid);
//     printf("%s %d\n",str,getpid());
//     return 0;
// }

// int main()
// {
//     printf("i am father pid:%d\n",getpid());
//     pid_t pid=fork();
//     if(pid==0)
//     {
//         //child
//         execlp("./mytest","mytest",NULL);
//     }
//     wait(NULL);

//     return 0;
// }

//exce
int main()
{
    pid_t pid=fork();
    
    if(pid<0)
    {
        perror("fork");
        exit(-1);
    }

    if(pid==0)               
    {
        //child
        char*const myargv[]=//ls -l
        {
            "ls",
            "-l",
            NULL
        };
        
        int exid;
        //exid=execl("/usr/bin/ls", "ls","-l", NULL);
        //exid=execlp("ls", "ls","-l", NULL);//推荐
        //exid=execv("/usr/bin/ls", myargv);
        exid=execvp("ls", myargv);

        printf("exec failed exid:%d\n",exid);
        exit(-1); // 如果子进程有此退出码，说明替换失败
    }

    int status=0;
    pid_t rid=waitpid(pid,&status,0);
    if (rid > 0)
    {
        printf("waitpid success pid:%d\n", rid);
        if (WIFEXITED(status))
        {
            printf("exit code:%d\n", WEXITSTATUS(status));
        }
        else
        {
            printf("kill by sig:%d\n", status & 0x7f);
        }
    }
    return 0; 
}

extern char** environ;

// int main()
// {
//     char* const argv[]=
//     {
//         "mytest",
//         NULL
//     };

//     char* const env[]=
//     {
//         "Myvalue=1030",
//         NULL
//     };

//     pid_t pid = fork();
    
//     if(pid<0)
//     {
//         perror("fork");
//         exit(-2);

//     }
//     else if(pid==0)
//     {
//         //child
//         int exid;
//        //char*path=getenv("PWD");
//        //exid= execle("./mytest","mytest",NULL,env);//*不带选项执行,但NULL一定记得要有
//        //exid = execvpe("./mytest",argv,env);//虽然是PATH，但是指定路径也行。
//        exid = execve("./mytest",argv,env);//系统调用，其余六个exec函数都是库函数，都是对execve的封装

//        printf("execle failed exid:%d\n",exid);
//        exit(exid);//-1

//     }
//     //father
//     int status=0;
//     pid_t rid=waitpid(pid,&status,0);
//     if(rid>0)
//     {
//         printf("waitpid success pid:%d\n",rid);
//         if(WIFEXITED(status))
//         {
//             printf("exit code:%d\n",WEXITSTATUS(status));
//         }
//         else
//         {
//             printf("kill by sig:%d\n",status&0x7f);
//         }
//     }

//     return 0;
// }